package com.teamall.framework.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.log4j.lf5.util.StreamUtils;



/**
 * RSA签名验签类
 */
public class RSASignature{
	
	/**
	 * 签名算法
	 */
	public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

	/**
	* RSA签名
	* @param content 待签名数据
	* @param privateKey 商户私钥
	* @param encode 字符集编码
	* @return 签名值
	*/
	public static String sign(String content, String privateKey, String encode)
	{
        try 
        {
        	PKCS8EncodedKeySpec priPKCS8 	= new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); 
        	
        	KeyFactory keyf 				= KeyFactory.getInstance("RSA");
        	PrivateKey priKey 				= keyf.generatePrivate(priPKCS8);

            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

            signature.initSign(priKey);
            signature.update( content.getBytes(encode));

            byte[] signed = signature.sign();
            
            return Base64.encode(signed);
        }
        catch (Exception e) 
        {
        	e.printStackTrace();
        }
        
        return null;
    }
	
	public static String sign(String content, String privateKey)
	{
        try 
        {
        	PKCS8EncodedKeySpec priPKCS8 	= new PKCS8EncodedKeySpec( Base64.decode(privateKey) ); 
        	KeyFactory keyf = KeyFactory.getInstance("RSA");
        	PrivateKey priKey = keyf.generatePrivate(priPKCS8);
            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
            signature.initSign(priKey);
            signature.update( content.getBytes("utf-8"));
            byte[] signed = signature.sign();
            return Base64.encode(signed);
        }
        catch (Exception e) 
        {
        	e.printStackTrace();
        }
        return null;
    }
	
	/**
	* RSA验签名检查
	* @param content 待签名数据
	* @param sign 签名值
	* @param publicKey 分配给开发商公钥
	* @param encode 字符集编码
	* @return 布尔值
	*/
	public static boolean doCheck(String content, String sign, String publicKey,String encode)
	{
		try 
		{
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	        byte[] encodedKey = Base64.decode(publicKey);
	        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

		
			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
		
			signature.initVerify(pubKey);
			signature.update( content.getBytes(encode) );
		
			boolean bverify = signature.verify( Base64.decode(sign) );
			return bverify;
			
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		
		return false;
	}
	
	public static boolean doCheck(String content, String sign, String publicKey)
	{
		try 
		{
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	        byte[] encodedKey = Base64.decode(publicKey);
	        PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

		
			java.security.Signature signature = java.security.Signature
			.getInstance(SIGN_ALGORITHMS);
		
			signature.initVerify(pubKey);
			signature.update( content.getBytes("UTF-8") );
		
			boolean bverify = signature.verify( Base64.decode(sign) );
			return bverify;
			
		}catch (Exception e){
			e.printStackTrace();
		}
		
		return false;
	}
	

    
    public static void main(String[] args) throws Exception {
		
		System.out.println("---------------私钥签名过程------------------");
//		char aa = 'Count=37&DataSet=[{"Name":"官网测试","FundFlow":"支出","Amount":38.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"待支付","TranDate":1449590400,"TranTime":1449626161,"OutTradeNo":"LG12345611"},{"Name":"官网测试","FundFlow":"支出","Amount":56.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"已支付","TranDate":1449504000,"TranTime":1449562398,"OutTradeNo":"LG12345611"},{"Name":"官网测试","FundFlow":"支出","Amount":67.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"已支付","TranDate":1449504000,"TranTime":1449562210,"OutTradeNo":"LG12345611"},{"Name":"官网测试","FundFlow":"支出","Amount":52.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"待支付","TranDate":1449504000,"TranTime":1449562137,"OutTradeNo":"LG12345611"},{"Name":"官网测试","FundFlow":"支出","Amount":23.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"已支付","TranDate":1449504000,"TranTime":1449561977,"OutTradeNo":"LG12345611"},{"Name":"官网测试","FundFlow":"支出","Amount":21.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"已支付","TranDate":1449504000,"TranTime":1449561810,"OutTradeNo":"LG12345611"},{"Name":"支付趟次TC201512100028费用","FundFlow":"支出","Amount":56.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"待支付","TranDate":1449504000,"TranTime":1449557918,"OutTradeNo":"TC201512100028"},{"Name":"支付趟次TC201512100028费用","FundFlow":"支出","Amount":56.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"待支付","TranDate":1449504000,"TranTime":1449557887,"OutTradeNo":"TC201512100028"},{"Name":"支付趟次TC201512100028费用","FundFlow":"支出","Amount":56.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"待支付","TranDate":1449504000,"TranTime":1449557014,"OutTradeNo":"TC201512100028"},{"Name":"支付趟次TC201512100028费用","FundFlow":"支出","Amount":56.0,"TradeType":"担保交易","PayerAccessToken":10000026,"IncomeAccessToken":10000011,"Status":"待支付","TranDate":1449504000,"TranTime":1449556816,"OutTradeNo":"TC201512100028"}]&Result=true&Timestamp=1449653287';
		String content="AccountName=10000011&AccountType=个人账户&AvailableAmount=158.00&Email=ndlinjian@126.com&FrozenAmount=0.00&IDCardNO=350432191001013233&Mobile=15659103095&Result=true&Timestamp=1449751561";
		String signstr=RSASignature.sign(content,RSAEncrypt.DEFAULT_PRIVATE_KEY);
		System.out.println("签名原串："+content);
		System.out.println("签名串："+signstr);
		System.out.println();
		
		System.out.println("---------------公钥校验签名------------------");
		System.out.println("签名原串："+content);
		signstr="3Jml2ie8tIzwWafrE0qdjqIqc2ntH16frY4oaTHZgn3KVX76wtc7K6h7QVJarEKn63h5VYn6jz44i0hkPkUJ3cbj8yPgAzSiGh52ki3o3je1pSjDychjgEIzEcrfJvnrMjgYTeLT2PndKQz49wH1jZh1aBve8hE5+NaZCRGQlMY=";
		System.out.println("签名串："+signstr);
		System.out.println("验签结果："+RSASignature.doCheck(content, signstr, RSAEncrypt.DEFAULT_SERVER_PUBLIC_KEY));
		System.out.println();
		
	}

}

